﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using FluentValidation;
using Microsoft.Practices.Unity;
using PicStore.BLL.Interface;
using PicStore.Common;
using PicStore.Common.Sorter;
using PicStore.Model;
using PicStore.Web.Lib;
using PicStore.Web.Models.Category;

namespace PicStore.Web.Controllers
{
    public class CategoryController : BaseController
    {
        [Dependency]
        public ICategoryService CategoryService { get; set; }

        public const int PageSize = 50;
        //
        // GET: /Category/

        public ActionResult Index()
        {
            return View();
        }

        //
        // GET: /Category/Details/5

        public ActionResult GetCategories(string name, string orderBy, int pageIndex = 1, bool isAsc = true)
        {
            string keyTosearch = string.Empty;
            if (string.IsNullOrEmpty(name) == false)
            {
                keyTosearch = name;
            }
            List<CategoryInfo> categoryItems = CategoryService.GetAllItems(keyTosearch);
            List<CategoryModel> list = (from t in categoryItems
                                        select CategoryModel.BuildCategoryModel(t)).ToList();
            IList<CategoryModel> sortedList = new SortList<CategoryModel, string>(list, orderBy, isAsc);

            int count = sortedList.Count();
            int totalPages = count / PageSize + (count % PageSize > 0 ? 1 : 0);

            IEnumerable<CategoryModel> result = sortedList.Skip((pageIndex - 1) * PageSize).Take(PageSize);
            return Json(new { Data = result.ToArray(), TotalPages = totalPages }, JsonRequestBehavior.AllowGet);
        }

        public ActionResult Add()
        {
            ViewBag.Action = "Add";
            ViewBag.OnSuccess = "viewModel.onDataAdded";
            var model = new CategoryModel();
            var categories = CategoryService.GetBaseCategoryListForAdmin();
            model.CategoryList = Utility.GetCategoryList(categories);
            return View("Add", model);
        }

        //
        // POST: /Category/Create

        [HttpPost]
        public ActionResult Add(CategoryModel model)
        {
            string errorPrefix = "Add category failed, ";
            try
            {
                var validator = new CategoryModelValidator();
                validator.ValidateAndThrow(model);

                // Add category item.
                string userName = HttpContext.User.Identity.Name;
                var user = UserService.GetUser(userName);
                int newItemId = CategoryService.CreateCategoryItem(model.CategoryId, model.ItemName, model.ItemValue,
                                                                       user.UserId,
                                                                       model.Description);
                CategoryInfo newInfo = CategoryService.GetCategoryItemById(newItemId);

                model = CategoryModel.BuildCategoryModel(newInfo);
                model.IsValid = true;
            }
            catch (ValidationException validateionExp)
            {
                StringBuilder builder = new StringBuilder();
                foreach (var failure in validateionExp.Errors)
                {
                    this.ModelState.AddModelError(failure.PropertyName, failure.ErrorMessage);
                    builder.AppendFormat("Field {0} has error: {1}", failure.PropertyName, failure.ErrorMessage);
                }
                model.IsValid = false;
                model.ErrorMessage = errorPrefix + builder.ToString();
            }
            catch (ArgumentException argExp)
            {
                model.IsValid = false;
                model.ErrorMessage = errorPrefix + argExp.Message;
            }
            catch (Exception e)
            {
                Log.Severe(e.ToString());

                model.IsValid = false;
                model.ErrorMessage = errorPrefix + Constants.SevereError + e.Message;
            }

            return Json(model);
        }

        //
        // GET: /Category/Edit/5

        public ActionResult Edit(int id)
        {
            ViewBag.Action = "Edit";
            ViewBag.OnSuccess = "viewModel.onDataUpdated";
            var category = CategoryService.GetCategoryItemById(id);
            var model = EditCategoryModel.BuildCategoryModel(category);
            var categories = CategoryService.GetBaseCategoryListForAdmin();
            model.CategoryList = Utility.GetCategoryList(categories);
            return View("Edit", model);
        }

        //
        // POST: /Category/Edit/5

        [HttpPost]
        public ActionResult Edit(EditCategoryModel model)
        {
            string errorPrefix = "Edit category failed, ";
            try
            {
                var validator = new EditCategoryModelValidator();
                validator.ValidateAndThrow(model);

                // Edit category item.
                string userName = HttpContext.User.Identity.Name;
                var user = UserService.GetUser(userName);
                CategoryService.UpdateCateoryItem(model.Id, model.ItemName, model.ItemValue,
                                                  model.CategoryId, user.UserId,
                                                  model.Description);

                model.IsValid = true;
            }
            catch (ValidationException validateionExp)
            {
                StringBuilder builder = new StringBuilder();
                foreach (var failure in validateionExp.Errors)
                {
                    this.ModelState.AddModelError(failure.PropertyName, failure.ErrorMessage);
                    builder.AppendFormat("Field {0} has error: {1}", failure.PropertyName, failure.ErrorMessage);
                }
                model.IsValid = false;
                model.ErrorMessage = errorPrefix + builder.ToString();
            }
            catch (ArgumentException argExp)
            {
                model.IsValid = false;
                model.ErrorMessage = errorPrefix + argExp.Message;
            }
            catch (Exception e)
            {
                Log.Severe(e.ToString());

                model.IsValid = false;
                model.ErrorMessage = errorPrefix + Constants.SevereError + e.Message;
            }

            CategoryInfo editInfo = CategoryService.GetCategoryItemById(model.Id);
            CategoryModel result = CategoryModel.BuildCategoryModel(editInfo);
            result.IsValid = model.IsValid;
            result.ErrorMessage = model.ErrorMessage;

            return Json(result);
        }

        //
        // GET: /Category/Delete/5

        public ActionResult Delete(int id)
        {
            var categoryItem = CategoryService.GetCategoryItemById(id);
            CategoryService.DeleteCateoryItem(id);
            return Json(CategoryModel.BuildCategoryModel(categoryItem), JsonRequestBehavior.AllowGet);
        }
    }
}
